home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb-4.5 / dist / gdb / cplus-dem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-29  |  27.0 KB  |  1,375 lines

  1. /* Demangler for GNU C++ 
  2.    Copyright 1989, 1991 Free Software Foundation, Inc.
  3.    written by James Clark (jjc@jclark.uucp)
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /* This is for g++ 1.95.03 (November 13 verison).  */
  20.  
  21. /* This file exports one function
  22.  
  23.    char *cplus_demangle (const char *name, int mode)
  24.  
  25.    If NAME is a mangled function name produced by GNU C++, then
  26.    a pointer to a malloced string giving a C++ representation
  27.    of the name will be returned; otherwise NULL will be returned.
  28.    It is the caller's responsibility to free the string which
  29.    is returned.
  30.  
  31.    If MODE > 0, then ANSI qualifiers such as `const' and `void' are output.
  32.    Otherwise they are not.
  33.    If MODE >= 0, parameters are emitted; otherwise not.
  34.  
  35.    For example,
  36.    
  37.    cplus_demangle ("foo__1Ai",  0)    => "A::foo(int)"
  38.    cplus_demangle ("foo__1Ai",  1)    => "A::foo(int)"
  39.    cplus_demangle ("foo__1Ai", -1)    => "A::foo"
  40.  
  41.    cplus_demangle ("foo__1Afe",  0)    => "A::foo(float,...)"
  42.    cplus_demangle ("foo__1Afe",  1)    => "A::foo(float,...)"
  43.    cplus_demangle ("foo__1Afe", -1)    => "A::foo"
  44.  
  45.    This file imports xmalloc and xrealloc, which are like malloc and
  46.    realloc except that they generate a fatal error if there is no
  47.    available memory. */
  48.  
  49. /* define this if names don't start with _ */
  50. /* #define nounderscore 1 */
  51.  
  52. /* GDB-specific, FIXME.  */
  53. #include "defs.h"
  54.  
  55. #include <ctype.h>
  56.  
  57. #ifdef USG
  58. #include <memory.h>
  59. #include <string.h>
  60. #else
  61. #include <strings.h>
  62. #endif
  63.  
  64. /* This is '$' on systems where the assembler can deal with that.
  65.    Where the assembler can't, it's '.' (but on many systems '.' is
  66.    used for other things).  */
  67. #if !defined (CPLUS_MARKER)
  68. #define CPLUS_MARKER '$'
  69. #endif
  70.  
  71. #ifndef __STDC__
  72. #define const
  73. #endif
  74.  
  75. #ifdef __STDC__
  76. extern char *cplus_demangle (const char *type, int mode);
  77. #else
  78. extern char *cplus_demangle ();
  79. #endif
  80.  
  81. static char **typevec = 0;
  82. static int ntypes = 0;
  83. static int typevec_size = 0;
  84.  
  85. const static struct optable {
  86.   const char *in;
  87.   const char *out;
  88.   int ansi;
  89. } optable[] = {
  90.   "nw", " new",    1,        /* new (1.92, ansi) */
  91.   "dl", " delete", 1,        /* new (1.92, ansi) */
  92.   "new", " new", 0,        /* old (1.91, and 1.x) */
  93.   "delete", " delete", 0,    /* old (1.91, and 1.x) */
  94.   "as", "=", 1,            /* ansi */
  95.   "ne", "!=", 1,        /* old, ansi */
  96.   "eq", "==", 1,        /* old, ansi */
  97.   "ge", ">=", 1,        /* old, ansi */
  98.   "gt", ">", 1,            /* old, ansi */
  99.   "le", "<=", 1,        /* old, ansi */
  100.   "lt", "<", 1,            /* old, ansi */
  101.   "plus", "+", 0,        /* old */
  102.   "pl", "+", 1,            /* ansi */
  103.   "apl", "+=", 1,        /* ansi */
  104.   "minus", "-", 0,        /* old */
  105.   "mi", "-", 1,            /* ansi */
  106.   "ami", "-=", 1,        /* ansi */
  107.   "mult", "*", 0,        /* old */
  108.   "ml", "*", 1,            /* ansi */
  109.   "aml", "*=", 1,        /* ansi */
  110.   "convert", "+", 0,        /* old (unary +) */
  111.   "negate", "-", 0,        /* old (unary -) */
  112.   "trunc_mod", "%", 0,        /* old */
  113.   "md", "%", 1,            /* ansi */
  114.   "amd", "%=", 1,        /* ansi */
  115.   "trunc_div", "/", 0,        /* old */
  116.   "dv", "/", 1,            /* ansi */
  117.   "adv", "/=", 1,        /* ansi */
  118.   "truth_andif", "&&", 0,    /* old */
  119.   "aa", "&&", 1,        /* ansi */
  120.   "truth_orif", "||", 0,    /* old */
  121.   "oo", "||", 1,        /* ansi */
  122.   "truth_not", "!", 0,        /* old */
  123.   "nt", "!", 1,            /* ansi */
  124.   "postincrement", "++", 0,    /* old */
  125.   "pp", "++", 1,        /* ansi */
  126.   "postdecrement", "--", 0,    /* old */
  127.   "mm", "--", 1,        /* ansi */
  128.   "bit_ior", "|", 0,        /* old */
  129.   "or", "|", 1,            /* ansi */
  130.   "aor", "|=", 1,        /* ansi */
  131.   "bit_xor", "^", 0,        /* old */
  132.   "er", "^", 1,            /* ansi */
  133.   "aer", "^=", 1,        /* ansi */
  134.   "bit_and", "&", 0,        /* old */
  135.   "ad", "&", 1,            /* ansi */
  136.   "aad", "&=", 1,        /* ansi */
  137.   "bit_not", "~", 0,        /* old */
  138.   "co", "~", 1,            /* ansi */
  139.   "call", "()", 0,        /* old */
  140.   "cl", "()", 1,        /* ansi */
  141.   "alshift", "<<", 0,        /* old */
  142.   "ls", "<<", 1,        /* ansi */
  143.   "als", "<<=", 1,        /* ansi */
  144.   "arshift", ">>", 0,        /* old */
  145.   "rs", ">>", 1,        /* ansi */
  146.   "ars", ">>=", 1,        /* ansi */
  147.   "component", "->", 0,        /* old */
  148.   "rf", "->", 1,        /* ansi */
  149.   "indirect", "*", 0,        /* old */
  150.   "method_call", "->()", 0,    /* old */
  151.   "addr", "&", 0,        /* old (unary &) */
  152.   "array", "[]", 0,        /* old */
  153.   "vc", "[]", 1,        /* ansi */
  154.   "compound", ",", 0,        /* old */
  155.   "cm", ",", 1,            /* ansi */
  156.   "cond", "?:", 0,        /* old */
  157.   "cn", "?:", 1,        /* psuedo-ansi */
  158.   "max", ">?", 0,        /* old */
  159.   "mx", ">?", 1,        /* psuedo-ansi */
  160.   "min", "<?", 0,        /* old */
  161.   "mn", "<?", 1,        /* psuedo-ansi */
  162.   "nop", "", 0,            /* old (for operator=) */
  163. };
  164.  
  165. /* Beware: these aren't '\0' terminated. */
  166.  
  167. typedef struct string {
  168.   char *b;            /* pointer to start of string */
  169.   char *p;            /* pointer after last character */
  170.   char *e;            /* pointer after end of allocated space */
  171. } string;
  172.  
  173. static void
  174. string_need PARAMS ((string *, int));
  175.  
  176. static void
  177. string_delete PARAMS ((string *));
  178.  
  179. static void
  180. string_init PARAMS ((string *));
  181.  
  182. static void
  183. string_clear PARAMS ((string *));
  184.  
  185. static int
  186. string_empty PARAMS ((string *));
  187.  
  188. static void
  189. string_append PARAMS ((string *, const char *));
  190.  
  191. static void
  192. string_appends PARAMS ((string *, string *));
  193.  
  194. static void
  195. string_appendn PARAMS ((string *, const char *, int));
  196.  
  197. static void
  198. string_prepend PARAMS ((string *, const char *));
  199.  
  200. static void
  201. string_prependn PARAMS ((string *, const char *, int));
  202.  
  203. static int
  204. get_count PARAMS ((const char **, int *));
  205.  
  206. static int
  207. do_args PARAMS ((const char **, string *, int));
  208.  
  209. static int
  210. do_type PARAMS ((const char **, string *, int));
  211.  
  212. static int
  213. do_arg PARAMS ((const char **, string *, int));
  214.  
  215. static void
  216. munge_function_name PARAMS ((string *, int));
  217.  
  218. static void
  219. remember_type PARAMS ((const char *, int));
  220.  
  221. #if 0
  222. static void
  223. string_prepends PARAMS ((string *, string *));
  224. #endif
  225.  
  226.  
  227. /* Takes operator name as e.g. "++" and returns mangled
  228.    operator name (e.g. "postincrement_expr"), or NULL if not found.
  229.  
  230.    If ARG_MODE == 1, return the ANSI name;
  231.    if ARG_MODE == 0 return the old GNU name.  */
  232. char *
  233. cplus_mangle_opname (opname, arg_mode)
  234.      char *opname;
  235.      int arg_mode;
  236. {
  237.   int i, len = strlen (opname);
  238.  
  239.   if (arg_mode != 0 && arg_mode != 1)
  240.     error ("invalid arg_mode");
  241.  
  242.   for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  243.     {
  244.       if (strlen (optable[i].out) == len
  245.       && arg_mode == optable[i].ansi
  246.       && memcmp (optable[i].out, opname, len) == 0)
  247.     return (char *)optable[i].in;
  248.     }
  249.   return 0;
  250. }
  251.  
  252. char *
  253. cplus_demangle (type, arg_mode)
  254.      const char *type;
  255.      int arg_mode;
  256. {
  257.   string decl;
  258.   int n;
  259.   int success = 0;
  260.   int constructor = 0;
  261.   int destructor = 0;
  262.   int static_type = 0;
  263.   int const_flag = 0;
  264.   int i;
  265.   const char *p;
  266. #ifndef LONGERNAMES
  267.   const char *premangle;
  268. #endif
  269.  
  270. # define print_ansi_qualifiers (arg_mode >  0)
  271. # define print_arg_types       (arg_mode >= 0)
  272.  
  273.   if (type == NULL || *type == '\0')
  274.     return NULL;
  275. #ifndef nounderscore
  276.   if (*type++ != '_')
  277.     return NULL;
  278. #endif
  279.   p = type;
  280.   while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  281.     p++;
  282.   if (*p == '\0')
  283.     {
  284.       /* destructor */
  285.       if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
  286.     {
  287.       int n;
  288.       char *tem;
  289.  
  290.       type += 3;        /* Get past _$_ at front.  */
  291.       while (isdigit (*type))
  292.         /* If there are digits at the front, it's because
  293.            of new 2.0 name mangling.  Just skip them.  */
  294.         type++;
  295.  
  296.       n = strlen (type)*2 + 3 + 2 + 1;
  297.       tem = (char *) xmalloc (n);
  298.       strcpy (tem, type);
  299.       strcat (tem, "::~");
  300.       strcat (tem, type);
  301.       if (print_arg_types)
  302.         strcat (tem, "()");
  303.       return tem;
  304.     }
  305.       /* static data member */
  306.       if (*type != '_' && (p = strchr (type, CPLUS_MARKER)) != NULL)
  307.     {
  308.       int n = strlen (type) + 2;
  309.       char *tem = (char *) xmalloc (n);
  310.       memcpy (tem, type, p - type);
  311.       strcpy (tem + (p - type), "::");
  312.       strcpy (tem + (p - type) + 2, p + 1);
  313.       return tem;
  314.     }
  315.       /* virtual table "_vt$"  */
  316.       if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
  317.     {
  318.       int n = strlen (type + 4) + 14 + 1;
  319.       char *tem = (char *) xmalloc (n);
  320.       strcpy (tem, type + 4);
  321.       strcat (tem, " virtual table");
  322.       return tem;
  323.     }
  324.       return NULL;
  325.     }
  326.  
  327.   string_init (&decl);
  328.  
  329.   if (static_type)
  330.     {
  331.       if (!isdigit (p[0]) && ('t' != p[0]))
  332.     {
  333.       string_delete (&decl);
  334.       return NULL;
  335.     }
  336.     }
  337.   else if (p == type)
  338.     {
  339.       if (!isdigit (p[2]) && ('t' != p[2]))
  340.     {
  341.       p += 1;
  342.       while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  343.         p++;
  344.       string_appendn (&decl, type, p - type);
  345.       string_need (&decl, 1);
  346.       *(decl.p) = '\0';
  347.       munge_function_name (&decl, 1);
  348.       if (decl.b[0] == '_')
  349.         {
  350.           string_delete (&decl);
  351.           return NULL;
  352.         }
  353.       else
  354.         p += 2;
  355.     }
  356.       else
  357.     {
  358.       constructor = 1;
  359.       p += 2;
  360.     }
  361.     }
  362.   else
  363.     {
  364.       string_appendn (&decl, type, p - type);
  365.       string_need (&decl, 1);
  366.       *(decl.p) = '\0';
  367.       munge_function_name (&decl, arg_mode);
  368.       p += 2;
  369.     }
  370.  
  371. #ifndef LONGERNAMES
  372.   premangle = p;
  373. #endif
  374.   switch (*p)
  375.     {
  376.     case 'C':
  377.       /* a const member function */
  378.       if (!isdigit (p[1]))
  379.     {
  380.       string_delete (&decl);
  381.       return NULL;
  382.     }
  383.       p += 1;
  384.       const_flag = 1;
  385.       /* fall through */
  386.     case '0':
  387.     case '1':
  388.     case '2':
  389.     case '3':
  390.     case '4':
  391.     case '5':
  392.     case '6':
  393.     case '7':
  394.     case '8':
  395.     case '9':
  396.       n = 0;
  397.       do
  398.     {
  399.       n *= 10;
  400.       n += *p - '0';
  401.       p += 1;
  402.     }
  403.       while (isdigit (*p));
  404.       if (strlen (p) < n)
  405.     {
  406.       string_delete (&decl);
  407.       return NULL;
  408.     }
  409.       if (constructor || destructor)
  410.     {
  411.       string_appendn (&decl, p, n);
  412.       string_append (&decl, "::");
  413.       if (destructor)
  414.         string_append(&decl, "~");
  415.       string_appendn (&decl, p, n);
  416.     }
  417.       else
  418.     {
  419.       string_prepend (&decl, "::");
  420.       string_prependn (&decl, p, n);
  421.     }
  422.       p += n;
  423. #ifndef LONGERNAMES
  424.       remember_type (premangle, p - premangle);
  425. #endif
  426.       if (static_type)
  427.     {
  428.       string_append(&decl, p+1);
  429.       p += strlen(p);
  430.       success = 1;
  431.     }
  432.       else
  433.     success = do_args (&p, &decl, arg_mode);
  434.       if (const_flag && print_arg_types)
  435.     string_append (&decl, " const");
  436.       break;
  437.     case 'F':
  438.       p += 1;
  439.       success = do_args (&p, &decl, arg_mode);
  440.       break;
  441.     /* template additions */
  442.     case 't':
  443.       p += 1;
  444.       {
  445.     int r, i;
  446.     string tname;
  447.     string trawname;
  448.     
  449.     string temp;
  450.     int need_comma = 0;
  451.     
  452.     string_init(&tname);
  453.     string_init(&trawname);
  454.     
  455.     /* get template name */
  456.     if (!get_count (&p, &r))
  457.       return 0;
  458.     string_appendn (&tname, p, r);
  459.     string_appendn (&trawname, p, r);
  460.     string_appendn (&trawname, "", 1);
  461.     p += r;
  462.     string_append (&tname, "<");
  463.     /* get size of template parameter list */
  464.     if (!get_count (&p, &r))
  465.       return 0;
  466.     for (i = 0; i < r; i++)
  467.       {
  468.         if (need_comma)
  469.           string_append (&tname, ", ");
  470.         /* Z for type parameters */
  471.         if (*p == 'Z')
  472.           {
  473.         p += 1;
  474.         
  475.         success = do_type (&p, &temp, arg_mode);
  476.         string_appendn (&temp, "", 1);
  477.         if (success)
  478.           string_append (&tname, temp.b);
  479.         string_delete(&temp);
  480.         if (!success)
  481.           break;
  482.           }
  483.         /* otherwise, value parameter */
  484.         else
  485.           {
  486.         const char *old_p  = p;
  487.         int is_pointer = 0;
  488.         int is_real = 0;
  489.         int is_integral = 0;
  490.         int done = 0;
  491.  
  492.         success = do_type (&p, &temp, arg_mode);
  493.         string_appendn (&temp, "", 1);
  494.         if (success)
  495.           string_append (&tname, temp.b);
  496.         string_delete(&temp);
  497.         if (!success)
  498.           break;
  499.         string_append (&tname, "=");
  500.         while (*old_p && !done)
  501.           {    
  502.             switch (*old_p)
  503.               {
  504.               case 'P':
  505.               case 'R':
  506.             done = is_pointer = 1;
  507.             break;
  508.               case 'C':    /* const */
  509.               case 'S':    /* explicitly signed [char] */
  510.               case 'U':    /* unsigned */
  511.               case 'V':    /* volatile */
  512.               case 'F':    /* function */
  513.               case 'M':    /* member function */
  514.               case 'O':    /* ??? */
  515.             old_p++;
  516.             continue;
  517.               case 'Q':    /* repetition of following */
  518.               case 'T':    /* remembered type */
  519.             abort();
  520.             break;
  521.               case 'v':    /* void */
  522.             abort();
  523.             break;
  524.               case 'x':    /* long long */
  525.               case 'l':    /* long */
  526.               case 'i':    /* int */
  527.               case 's':    /* short */
  528.               case 'c':    /* char */
  529.             done = is_integral = 1;
  530.             break;
  531.               case 'r':    /* long double */
  532.               case 'd':    /* double */
  533.               case 'f':    /* float */
  534.             done = is_real = 1;
  535.             break;
  536.               default:
  537.             abort();
  538.               }
  539.           }
  540.         if (is_integral)
  541.           {
  542.             if (*p == 'm')
  543.               {
  544.             string_appendn (&tname, "-", 1);
  545.             p++;
  546.               }
  547.             while (isdigit (*p))    
  548.               {
  549.             string_appendn (&tname, p, 1);
  550.             p++;
  551.               }
  552.           }
  553.         else if (is_real)
  554.           {
  555.             if (*p == 'm')
  556.               {
  557.             string_appendn (&tname, "-", 1);
  558.             p++;
  559.               }
  560.             while (isdigit (*p))    
  561.               {
  562.             string_appendn (&tname, p, 1);
  563.             p++;
  564.               }
  565.             if (*p == '.') /* fraction */
  566.               {
  567.             string_appendn (&tname, ".", 1);
  568.             p++;
  569.             while (isdigit (*p))    
  570.               {
  571.                 string_appendn (&tname, p, 1);
  572.                 p++;
  573.               }
  574.               }
  575.             if (*p == 'e') /* exponent */
  576.               {
  577.             string_appendn (&tname, "e", 1);
  578.             p++;
  579.             while (isdigit (*p))    
  580.               {
  581.                 string_appendn (&tname, p, 1);
  582.                 p++;
  583.               }
  584.               }
  585.           }
  586.         else if (is_pointer)
  587.           {
  588.             int symbol_len;
  589.             
  590.             if (!get_count (&p, &symbol_len))
  591.               {
  592.             success = 0;
  593.             break;
  594.               }
  595.             string_appendn (&tname, p, symbol_len);
  596.             p += symbol_len;
  597.           }
  598.           }
  599.         need_comma = 1;
  600.       }
  601.     string_append (&tname, ">::");
  602.     if (destructor)
  603.       string_append(&tname, "~");
  604.     if (constructor || destructor) {
  605.       string_append (&tname, trawname.b);
  606.     }
  607.     string_delete(&trawname);
  608.     
  609.     if (!success) {
  610.       string_delete(&tname);
  611.       return 0;
  612.     }
  613.     string_prepend (&decl, tname.b);
  614.     string_delete(&tname);
  615.  
  616.     if (static_type)
  617.       {
  618.         string_append(&decl, p+1);
  619.         p += strlen(p);
  620.         success = 1;
  621.       }
  622.     else
  623.       success = do_args (&p, &decl, arg_mode);
  624.     break;
  625.       }
  626.     }
  627.  
  628.   for (i = 0; i < ntypes; i++)
  629.     if (typevec[i] != NULL)
  630.       free (typevec[i]);
  631.   ntypes = 0;
  632.   if (typevec != NULL)
  633.     {
  634.       free ((char *)typevec);
  635.       typevec = NULL;
  636.       typevec_size = 0;
  637.     }
  638.  
  639.   if (success)
  640.     {
  641.       string_appendn (&decl, "", 1);
  642.       return decl.b;
  643.     }
  644.   else
  645.     {
  646.       string_delete (&decl);
  647.       return NULL;
  648.     }
  649. }
  650.  
  651. static int
  652. get_count (type, count)
  653.      const char **type;
  654.      int *count;
  655. {
  656.   if (!isdigit (**type))
  657.     return 0;
  658.   *count = **type - '0';
  659.   *type += 1;
  660.   /* see flush_repeats in cplus-method.c */
  661.   if (isdigit (**type))
  662.     {
  663.       const char *p = *type;
  664.       int n = *count;
  665.       do 
  666.     {
  667.       n *= 10;
  668.       n += *p - '0';
  669.       p += 1;
  670.     } 
  671.       while (isdigit (*p));
  672.       if (*p == '_')
  673.     {
  674.       *type = p + 1;
  675.       *count = n;
  676.     }
  677.     }
  678.   return 1;
  679. }
  680.  
  681. /* result will be initialised here; it will be freed on failure */
  682.  
  683. static int
  684. do_type (type, result, arg_mode)
  685.      const char **type;
  686.      string *result;
  687.      int arg_mode;
  688. {
  689.   int n;
  690.   int done;
  691.   int non_empty = 0;
  692.   int success;
  693.   string decl;
  694.   const char *remembered_type;
  695.  
  696.   string_init (&decl);
  697.   string_init (result);
  698.  
  699.   done = 0;
  700.   success = 1;
  701.   while (success && !done)
  702.     {
  703.       int member;
  704.       switch (**type)
  705.     {
  706.     case 'Q':
  707.       n = (*type)[1] - '0';
  708.       if (n < 0 || n > 9)
  709.         success = 0;
  710.       *type += 2;
  711.       while (n-- > 0)
  712.         do_type (type, result, arg_mode);
  713.       break;
  714.  
  715.     case 'P':
  716.       *type += 1;
  717.       string_prepend (&decl, "*");
  718.       break;
  719.  
  720.     case 'R':
  721.       *type += 1;
  722.       string_prepend (&decl, "&");
  723.       break;
  724.  
  725.     case 'T':
  726.       *type += 1;
  727.       if (!get_count (type, &n) || n >= ntypes)
  728.         success = 0;
  729.       else
  730.         {
  731.           remembered_type = typevec[n];
  732.           type = &remembered_type;
  733.         }
  734.       break;
  735.  
  736.     case 'F':
  737.       *type += 1;
  738.       if (!string_empty (&decl) && decl.b[0] == '*')
  739.         {
  740.           string_prepend (&decl, "(");
  741.           string_append (&decl, ")");
  742.         }
  743.       if (!do_args (type, &decl, arg_mode) || **type != '_')
  744.         success = 0;
  745.       else
  746.         *type += 1;
  747.       break;
  748.  
  749.     case 'M':
  750.     case 'O':
  751.       {
  752.         int constp = 0;
  753.         int volatilep = 0;
  754.  
  755.         member = **type == 'M';
  756.         *type += 1;
  757.         if (!isdigit (**type))
  758.           {
  759.         success = 0;
  760.         break;
  761.           }
  762.         n = 0;
  763.         do
  764.           {
  765.         n *= 10;
  766.         n += **type - '0';
  767.         *type += 1;
  768.           } 
  769.         while (isdigit (**type));
  770.         if (strlen (*type) < n)
  771.           {
  772.         success = 0;
  773.         break;
  774.           }
  775.         string_append (&decl, ")");
  776.         string_prepend (&decl, "::");
  777.         string_prependn (&decl, *type, n);
  778.         string_prepend (&decl, "(");
  779.         *type += n;
  780.         if (member)
  781.           {
  782.         if (**type == 'C')
  783.           {
  784.             *type += 1;
  785.             constp = 1;
  786.           }
  787.         if (**type == 'V')
  788.           {
  789.             *type += 1;
  790.             volatilep = 1;
  791.           }
  792.         if (*(*type)++ != 'F')
  793.           {
  794.             success = 0;
  795.             break;
  796.           }
  797.           }
  798.         if ((member && !do_args (type, &decl, arg_mode)) || **type != '_')
  799.           {
  800.         success = 0;
  801.         break;
  802.           }
  803.         *type += 1;
  804.         if (! print_ansi_qualifiers)
  805.           break;
  806.         if (constp)
  807.           {
  808.         if (non_empty)
  809.           string_append (&decl, " ");
  810.         else
  811.           non_empty = 1;
  812.         string_append (&decl, "const");
  813.           }
  814.         if (volatilep)
  815.           {
  816.         if (non_empty)
  817.           string_append (&decl, " ");
  818.         else
  819.           non_empty = 1;
  820.         string_append (&decl, "volatile");
  821.           }
  822.         break;
  823.       }
  824.  
  825.     case 'C':
  826.       if ((*type)[1] == 'P')
  827.         {
  828.           *type += 1;
  829.           if (print_ansi_qualifiers)
  830.         {
  831.           if (!string_empty (&decl))
  832.             string_prepend (&decl, " ");
  833.           string_prepend (&decl, "const");
  834.         }
  835.           break;
  836.         }
  837.  
  838.       /* fall through */
  839.     default:
  840.       done = 1;
  841.       break;
  842.     }
  843.     }
  844.  
  845.   done = 0;
  846.   non_empty = 0;
  847.   while (success && !done)
  848.     {
  849.       switch (**type)
  850.     {
  851.     case 'C':
  852.       *type += 1;
  853.       if (print_ansi_qualifiers)
  854.         {
  855.           if (non_empty)
  856.         string_append (result, " ");
  857.           else
  858.         non_empty = 1;
  859.           string_append (result, "const");
  860.         }
  861.       break;
  862.     case 'U':
  863.       *type += 1;
  864.       if (non_empty)
  865.         string_append (result, " ");
  866.       else
  867.         non_empty = 1;
  868.       string_append (result, "unsigned");
  869.       break;
  870.     case 'S': /* signed char only */
  871.       *type += 1;
  872.       if (non_empty)
  873.         string_append (result, " ");
  874.       else
  875.         non_empty = 1;
  876.       string_append (result, "signed");
  877.       break;
  878.     case 'V':
  879.       *type += 1;
  880.       if (print_ansi_qualifiers)
  881.         {
  882.           if (non_empty)
  883.         string_append (result, " ");
  884.           else
  885.         non_empty = 1;
  886.           string_append (result, "volatile");
  887.         }
  888.       break;
  889.     default:
  890.       done = 1;
  891.       break;
  892.     }
  893.     }
  894.  
  895.   if (success)
  896.     switch (**type)
  897.       {
  898.       case '\0':
  899.       case '_':
  900.     break;
  901.       case 'v':
  902.     *type += 1;
  903.     if (non_empty)
  904.       string_append (result, " ");
  905.     string_append (result, "void");
  906.     break;
  907.       case 'x':
  908.     *type += 1;
  909.     if (non_empty)
  910.       string_append (result, " ");
  911.     string_append (result, "long long");
  912.     break;
  913.       case 'l':
  914.     *type += 1;
  915.     if (non_empty)
  916.       string_append (result, " ");
  917.     string_append (result, "long");
  918.     break;
  919.       case 'i':
  920.     *type += 1;
  921.     if (non_empty)
  922.       string_append (result, " ");
  923.     string_append (result, "int");
  924.     break;
  925.       case 's':
  926.     *type += 1;
  927.     if (non_empty)
  928.       string_append (result, " ");
  929.     string_append (result, "short");
  930.     break;
  931.       case 'c':
  932.     *type += 1;
  933.     if (non_empty)
  934.       string_append (result, " ");
  935.     string_append (result, "char");
  936.     break;
  937.       case 'r':
  938.     *type += 1;
  939.     if (non_empty)
  940.       string_append (result, " ");
  941.     string_append (result, "long double");
  942.     break;
  943.       case 'd':
  944.     *type += 1;
  945.     if (non_empty)
  946.       string_append (result, " ");
  947.     string_append (result, "double");
  948.     break;
  949.       case 'f':
  950.     *type += 1;
  951.     if (non_empty)
  952.       string_append (result, " ");
  953.     string_append (result, "float");
  954.     break;
  955.       case 'G':
  956.     *type += 1;
  957.     if (!isdigit (**type))
  958.       {
  959.         success = 0;
  960.         break;
  961.       }
  962.     /* fall through */
  963.       case '0':
  964.       case '1':
  965.       case '2':
  966.       case '3':
  967.       case '4':
  968.       case '5':
  969.       case '6':
  970.       case '7':
  971.       case '8':
  972.       case '9':
  973.     n = 0;
  974.     do
  975.       {
  976.         n *= 10;
  977.         n += **type - '0';
  978.         *type += 1;
  979.       }
  980.     while (isdigit (**type));
  981.     if (strlen (*type) < n)
  982.       {
  983.         success = 0;
  984.         break;
  985.       }
  986.     if (non_empty)
  987.       string_append (result, " ");
  988.     string_appendn (result, *type, n);
  989.     *type += n;
  990.     break;
  991.       default:
  992.     success = 0;
  993.     break;
  994.       }
  995.  
  996.   if (success)
  997.     {
  998.       if (!string_empty (&decl))
  999.     {
  1000.       string_append (result, " ");
  1001.       string_appends (result, &decl);
  1002.     }
  1003.       string_delete (&decl);
  1004.       return 1;
  1005.     }
  1006.   else
  1007.     {
  1008.       string_delete (&decl);
  1009.       string_delete (result);
  1010.       return 0;
  1011.     }
  1012. }
  1013.  
  1014. /* `result' will be initialised in do_type; it will be freed on failure */
  1015.  
  1016. static int
  1017. do_arg (type, result, arg_mode)
  1018.      const char **type;
  1019.      string *result;
  1020.      int arg_mode;
  1021. {
  1022.   const char *start = *type;
  1023.  
  1024.   if (!do_type (type, result, arg_mode))
  1025.     return 0;
  1026.   remember_type (start, *type - start);
  1027.   return 1;
  1028. }
  1029.  
  1030. static void
  1031. remember_type (start, len)
  1032.      const char *start;
  1033.      int len;
  1034. {
  1035.   char *tem;
  1036.  
  1037.   if (ntypes >= typevec_size)
  1038.     {
  1039.       if (typevec_size == 0)
  1040.     {
  1041.       typevec_size = 3;
  1042.       typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
  1043.     }
  1044.       else
  1045.     {
  1046.       typevec_size *= 2;
  1047.       typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
  1048.     }
  1049.     }
  1050.   tem = (char *) xmalloc (len + 1);
  1051.   memcpy (tem, start, len);
  1052.   tem[len] = '\0';
  1053.   typevec[ntypes++] = tem;
  1054. }
  1055.  
  1056. /* `decl' must be already initialised, usually non-empty;
  1057.    it won't be freed on failure */
  1058.  
  1059. static int
  1060. do_args (type, decl, arg_mode)
  1061.      const char **type;
  1062.      string *decl;
  1063.      int arg_mode;
  1064. {
  1065.   string arg;
  1066.   int need_comma = 0;
  1067.  
  1068.   if (print_arg_types)
  1069.     string_append (decl, "(");
  1070.  
  1071.   while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
  1072.     {
  1073.       if (**type == 'N')
  1074.     {
  1075.       int r;
  1076.       int t;
  1077.       *type += 1;
  1078.       if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
  1079.         return 0;
  1080.       while (--r >= 0)
  1081.         {
  1082.           const char *tem = typevec[t];
  1083.           if (need_comma && print_arg_types)
  1084.         string_append (decl, ", ");
  1085.           if (!do_arg (&tem, &arg, arg_mode))
  1086.         return 0;
  1087.           if (print_arg_types)
  1088.         string_appends (decl, &arg);
  1089.           string_delete (&arg);
  1090.           need_comma = 1;
  1091.         }
  1092.     }
  1093.       else
  1094.     {
  1095.       if (need_comma & print_arg_types)
  1096.         string_append (decl, ", ");
  1097.       if (!do_arg (type, &arg, arg_mode))
  1098.         return 0;
  1099.       if (print_arg_types)
  1100.         string_appends (decl, &arg);
  1101.       string_delete (&arg);
  1102.       need_comma = 1;
  1103.     }
  1104.     }
  1105.  
  1106.   if (**type == 'v')
  1107.     *type += 1;
  1108.   else if (**type == 'e')
  1109.     {
  1110.       *type += 1;
  1111.       if (print_arg_types)
  1112.     {
  1113.       if (need_comma)
  1114.         string_append (decl, ",");
  1115.       string_append (decl, "...");
  1116.     }
  1117.     }
  1118.  
  1119.   if (print_arg_types)
  1120.     string_append (decl, ")");
  1121.   return 1;
  1122. }
  1123.  
  1124. static void
  1125. munge_function_name (name, arg_mode)
  1126.      string *name;
  1127.      int arg_mode;
  1128. {
  1129.   if (string_empty (name))
  1130.     return;
  1131.  
  1132.   if (name->p - name->b >= 3 
  1133.       && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == CPLUS_MARKER)
  1134.     {
  1135.       int i;
  1136.       /* see if it's an assignment expression */
  1137.       if (name->p - name->b >= 10 /* op$assign_ */
  1138.       && memcmp (name->b + 3, "assign_", 7) == 0)
  1139.     {
  1140.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1141.         {
  1142.           int len = name->p - name->b - 10;
  1143.           if (strlen (optable[i].in) == len
  1144.           && memcmp (optable[i].in, name->b + 10, len) == 0)
  1145.         {
  1146.           string_clear (name);
  1147.           string_append (name, "operator");
  1148.           string_append (name, optable[i].out);
  1149.           string_append (name, "=");
  1150.           return;
  1151.         }
  1152.         }
  1153.     }
  1154.       else
  1155.     {
  1156.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1157.         {
  1158.           int len = name->p - name->b - 3;
  1159.           if (strlen (optable[i].in) == len 
  1160.           && memcmp (optable[i].in, name->b + 3, len) == 0)
  1161.         {
  1162.           string_clear (name);
  1163.           string_append (name, "operator");
  1164.           string_append (name, optable[i].out);
  1165.           return;
  1166.         }
  1167.         }
  1168.     }
  1169.       return;
  1170.     }
  1171.   else if (name->p - name->b >= 5 && memcmp (name->b, "type$", 5) == 0)
  1172.     {
  1173.       /* type conversion operator */
  1174.       string type;
  1175.       const char *tem = name->b + 5;
  1176.       if (do_type (&tem, &type, arg_mode))
  1177.     {
  1178.       string_clear (name);
  1179.       string_append (name, "operator ");
  1180.       string_appends (name, &type);
  1181.       string_delete (&type);
  1182.       return;
  1183.     }
  1184.     }
  1185.   /* ANSI.  */
  1186.   else if (name->b[2] == 'o' && name->b[3] == 'p')
  1187.     {
  1188.       /* type conversion operator.  */
  1189.       string type;
  1190.       const char *tem = name->b + 4;
  1191.       if (do_type (&tem, &type, arg_mode))
  1192.     {
  1193.       string_clear (name);
  1194.       string_append (name, "operator ");
  1195.       string_appends (name, &type);
  1196.       string_delete (&type);
  1197.       return;
  1198.     }
  1199.     }
  1200.   else if (name->b[0] == '_' && name->b[1] == '_'
  1201.        && name->b[2] >= 'a' && name->b[2] <= 'z'
  1202.        && name->b[3] >= 'a' && name->b[3] <= 'z')
  1203.     {
  1204.       int i;
  1205.  
  1206.       if (name->b[4] == '\0')
  1207.     {
  1208.       /* Operator.  */
  1209.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1210.         {
  1211.           if (strlen (optable[i].in) == 2
  1212.           && memcmp (optable[i].in, name->b + 2, 2) == 0)
  1213.         {
  1214.           string_clear (name);
  1215.           string_append (name, "operator");
  1216.           string_append (name, optable[i].out);
  1217.           return;
  1218.         }
  1219.         }
  1220.     }
  1221.       else
  1222.     {
  1223.       if (name->b[2] != 'a' || name->b[5] != '\0')
  1224.         return;
  1225.       /* Assignment.  */
  1226.       for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
  1227.         {
  1228.           if (strlen (optable[i].in) == 3
  1229.           && memcmp (optable[i].in, name->b + 2, 3) == 0)
  1230.         {
  1231.           string_clear (name);
  1232.           string_append (name, "operator");
  1233.           string_append (name, optable[i].out);
  1234.           return;
  1235.         }
  1236.         }
  1237.     }
  1238.     }
  1239. }
  1240.  
  1241. /* a mini string-handling package */
  1242.  
  1243. static void
  1244. string_need (s, n)
  1245.      string *s;
  1246.      int n;
  1247. {
  1248.   if (s->b == NULL)
  1249.     {
  1250.       if (n < 32)
  1251.     n = 32;
  1252.       s->p = s->b = (char *) xmalloc (n);
  1253.       s->e = s->b + n;
  1254.     }
  1255.   else if (s->e - s->p < n)
  1256.     {
  1257.       int tem = s->p - s->b;
  1258.       n += tem;
  1259.       n *= 2;
  1260.       s->b = (char *) xrealloc (s->b, n);
  1261.       s->p = s->b + tem;
  1262.       s->e = s->b + n;
  1263.     }
  1264. }
  1265.  
  1266. static void
  1267. string_delete (s)
  1268.      string *s;
  1269. {
  1270.   if (s->b != NULL)
  1271.     {
  1272.       free (s->b);
  1273.       s->b = s->e = s->p = NULL;
  1274.     }
  1275. }
  1276.  
  1277. static void
  1278. string_init (s)
  1279.      string *s;
  1280. {
  1281.   s->b = s->p = s->e = NULL;
  1282. }
  1283.  
  1284. static void 
  1285. string_clear (s)
  1286.      string *s;
  1287. {
  1288.   s->p = s->b;
  1289. }
  1290.  
  1291. static int
  1292. string_empty (s)
  1293.      string *s;
  1294. {
  1295.   return s->b == s->p;
  1296. }
  1297.  
  1298. static void
  1299. string_append (p, s)
  1300.      string *p;
  1301.      const char *s;
  1302. {
  1303.   int n;
  1304.   if (s == NULL || *s == '\0')
  1305.     return;
  1306.   n = strlen (s);
  1307.   string_need (p, n);
  1308.   memcpy (p->p, s, n);
  1309.   p->p += n;
  1310. }
  1311.  
  1312. static void
  1313. string_appends (p, s)
  1314.      string *p, *s;
  1315. {
  1316.   int n;
  1317.   if (s->b == s->p)
  1318.     return;
  1319.   n = s->p - s->b;
  1320.   string_need (p, n);
  1321.   memcpy (p->p, s->b, n);
  1322.   p->p += n;
  1323. }
  1324.  
  1325. static void
  1326. string_appendn (p, s, n)
  1327.      string *p;
  1328.      const char *s;
  1329.      int n;
  1330. {
  1331.   if (n == 0)
  1332.     return;
  1333.   string_need (p, n);
  1334.   memcpy (p->p, s, n);
  1335.   p->p += n;
  1336. }
  1337.  
  1338. static void
  1339. string_prepend (p, s)
  1340.      string *p;
  1341.      const char *s;
  1342. {
  1343.   if (s == NULL || *s == '\0')
  1344.     return;
  1345.   string_prependn (p, s, strlen (s));
  1346. }
  1347.  
  1348. #if 0
  1349. static void
  1350. string_prepends (p, s)
  1351.      string *p, *s;
  1352. {
  1353.   if (s->b == s->p)
  1354.     return;
  1355.   string_prependn (p, s->b, s->p - s->b);
  1356. }
  1357. #endif
  1358.  
  1359. static void
  1360. string_prependn (p, s, n)
  1361.      string *p;
  1362.      const char *s;
  1363.      int n;
  1364. {
  1365.   char *q;
  1366.  
  1367.   if (n == 0)
  1368.     return;
  1369.   string_need (p, n);
  1370.   for (q = p->p - 1; q >= p->b; q--)
  1371.     q[n] = q[0];
  1372.   memcpy (p->b, s, n);
  1373.   p->p += n;
  1374. }
  1375.